package com.andnnl.guava;

import com.nurkiewicz.asyncretry.AsyncRetryExecutor;
import com.nurkiewicz.asyncretry.RetryExecutor;

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * 异步任务，重试
 * Created by chenss on 2021/4/28.
 */
public class AsyncRetryExecutorTest {
    public static void main(String[] args) {
//        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);
        RetryExecutor executor = new AsyncRetryExecutor(scheduler)
                .retryOn(Exception.class)
//                .withExponentialBackoff(500, 2)     //500ms times 2 after each retry,重试之间的间隔呈指数增长 如：等待两次（200ms）。 再过400毫秒，800毫秒
//                .withMaxDelay(10_000)               //10 seconds  最大等10秒，跟withExponentialBackoff一起用

                .withFixedBackoff(1000)//固定200ms
                .withFixedRate()

//                .withUniformJitter()                //add between +/- 100 ms randomly 随机抖动
                .withMaxRetries(3);
        for (int i = 0; i < 2; i++) {
            long lastTime = System.currentTimeMillis();
            System.out.println("lastTime:" + lastTime);

            int finalI = i;
//            executor.
//                    getWithRetry(() -> {
//                        System.out.println(finalI + "start to connect " + System.currentTimeMillis());
//                        return new Socket("localhost", 8080);
//                    }).
//                    whenComplete((socket, error) -> {
//                        if (socket != null) {
//                            //connected OK, proceed
//                            System.out.println("OK");
//                        } else {
//                            error.printStackTrace();
//                            System.out.println("Can't connect, last error:" + error);
//                        }
//                    });
            executor.
                    getWithRetry(new Callable<Boolean>() {
                        int time = 0;
                        @Override
                        public Boolean call() throws Exception {
                            System.out.println("retry "+time);
                            if (time++ == 0)
                                throw new RuntimeException("first retry");
                            if(1==1)
                                throw new RuntimeException("to retry");
                            return Boolean.TRUE;
                        }
                    }).
                    whenComplete((rs, error) -> {
                        if (rs != null) {
                            //connected OK, proceed
                            System.out.println("OK");
                        } else {
                            error.printStackTrace();
                            System.out.println("Can't connect, last error:" + error);
                        }
                    });
        }
        System.out.println(" all task start...");
    }
}
